package view;

import common.Constant;
import components.MButton;
import operator.Handler;
import platform.MeanLabel;
import platform.MeanPlatform;
import platform.SelectLabel;
import pri.swg.Slider;
import common.Singleton;
import vo.Mean;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;

/**
 * 控制右属性面板及几个滑动菜单
 *
 * @author 柴家琪
 *
 */
public class ViewControl {
    private static ViewControl viewControl;
    private Main m;
    private Slider sliderOfTextOps, sliderOfMeanOps, sliderOfLocSelector, sliderOfAttrSetter;
    private JPanel textOpsMenu, rightPanel, meanOpsMenu, locSelecter, info, atterSetter;
    //	private LineAZer info_charNum,info_main,info_all;
    private JLabel info_charNums, info_mainNums, info_allNums;
    public final int pre = 1, charN = 2, main = 3, all = 4, ALL = 5;
    private JScrollPane scrollLocSelector;
    private Handler handler;
    private ArrayList<MeanPlatform> meanPlatforms = new ArrayList<>();// 平台队列
    // Attr设置↓
    public int preType;

    private ViewControl() {
        this.m = Main.main;
        m.view = this;
    }
    public static ViewControl getViewControl() {
        if(viewControl == null) {
            viewControl = new ViewControl();
            viewControl.handler = Singleton.handler();
        }
        return viewControl;
    }

    // 显式Explicit隐式Implicit
    public MeanLabel preSelected;
    //	public Border preBorder;
    public int lastOrder = -1000;
    public int requiredHeight = 0;

    public Mean preMean = null;

    /**
     * 当所有必要组件添加完之后，启动此方法
     */
    public void SetUp() {
        textOpsMenu = m.textOpsMenu;
        rightPanel = m.rightPanel;
        info = m.info;
        meanOpsMenu = m.meanOpsMenu;
        locSelecter = m.locSelector;
        scrollLocSelector = m.scrollLocSelector;
        atterSetter = m.attrSetter;

        sliderOfTextOps = Slider.direct(textOpsMenu, Slider.RIGHT, textOpsMenu.getWidth(), 100, Slider.RETURN);
        sliderOfMeanOps = Slider.direct(meanOpsMenu, Slider.LEFT, meanOpsMenu.getWidth(), 100, Slider.RETURN);
        sliderOfLocSelector = Slider.direct(scrollLocSelector, Slider.RIGHT, scrollLocSelector.getWidth(), 100, Slider.RETURN);
        sliderOfAttrSetter = Slider.direct(atterSetter, Slider.RIGHT, atterSetter.getWidth(), 100, Slider.RETURN);
    }

    public void reSetOrder() {
        if (preSelected != null)
            preSelected.getGroup_plat().beSelected(false);
//		if(preBorder!=null&&preSelected!=null)
//			preSelected.setBorder(preBorder);
        preSelected = null;
//		preBorder=null;
        lastOrder = -1000;
        info_refreshInfo(pre);
    }

    /**
     * 召回所有的滑动菜单 并初始化所有操作数据
     */
    public void callBackAll() {
        if (sliderOfAttrSetter.isGoing()) {
            int py = atterSetter.getY();
            sliderOfAttrSetter.setStart(new Point(-atterSetter.getWidth(), py));
            sliderOfAttrSetter.setFinish(new Point(0, py));// shower可移动 error point:shower改变的只有y，x=0或者-width
        }
        sliderOfTextOps.goBack();
        sliderOfMeanOps.goBack();
        sliderOfLocSelector.goBack();
        sliderOfAttrSetter.goBack();
    }

    /**
     * 根据 strings 参数添加按钮面板的按钮
     */
    private void s_add(JPanel ops, Slider s_, boolean clear, String... strings) {
        if (clear)
            ops.removeAll();
        for (String string : strings) {
            switch (string) {
                case "Add_mean":
                    ops.add(createButton("增加意向（链）", MButton.Add_mean, new Color(255, 204, 102), 165, s_));
                    break;
                case "Combine":
                    ops.add(createButton("归并到已有意象", MButton.Combine, new Color(255, 204, 102), 145, s_));
                    break;
                case "Apart":
                    ops.add(createButton("独立", MButton.Apart, Color.GREEN, 132, s_));
                    break;
                case "Revoke":
                    ops.add(createButton("取消操作", MButton.Revoke, new Color(255, 50, 50), 132, s_));
                    break;///
                case "Revoke_last":
                    ops.add(createButton("撤销上一个", MButton.Revoke_last, new Color(255, 122, 122), 145, s_));
                    break;
                case "Add_SelfAttr":
                    ops.add(createButton("增加此意象的属性", MButton.Add_SelfAttr, new Color(255, 102, 204), 165, s_));
                    break;///
                case "Add_Loc":
                    ops.add(createButton("增加意象的位置", MButton.Add_Loc, new Color(102, 204, 255), 165, s_));
                    break;
                case "Delete":
                    ops.add(createButton("删除", MButton.Delete, new Color(255, 50, 50), 132, s_));
                    break;//
                case "Modify":
                    ops.add(createButton("修改", MButton.Modify, new Color(50, 50, 255), 132, s_));
                    break;//
                case "Confirm":
                    ops.add(createButton("确认", MButton.Confirm, new Color(50, 255, 50), 132, s_));
                    break;//
            }
        }
    }

    private MButton createButton(String title, int order, Color aim, int length, Slider s) {
        MButton b = new MButton(title, order, aim, 14, s);
        b.setPreferredSize(new Dimension(length, textOpsMenu.getHeight()));
        return b;
    }

    private void textOpsAddAndGo(String... strings) {
        callBackAll();// 召回所有已经显示的菜单
        s_add(textOpsMenu, sliderOfTextOps, true, strings);
        info_refreshInfo(pre);
        sliderOfTextOps.goOn();
    }

    /*******************************************
     * 向意象面板中添加（或重新添加）标签
     */
    public void attr_addAll() {
        rightPanel.removeAll();
        meanPlatforms.clear();
        Collections.sort(handler.mainMean);// 排序

        int id = 1;
        for (Mean mean: handler.mainMean) {
            attr_addChain(mean, id++);
        }
        info_refreshInfo(ALL);
    }

    /**
     * 添加意象
     *
     * @param m 主意象
     */
    private void attr_addChain(Mean m, int id) {
        MeanLabel[] labels = MeanLabel.getAllLabel(m, id);// 获取主意象所有labels
        MeanLabel topLabel = labels[0];// labels[0]是显示意象文字的那个标签
        Mean temp;
        temp = m.getInner_id() == 0 ? m.getNext() : m.getMain().getNext();
        while (temp != null) {
            if (temp.getInner_id() != m.getInner_id()) {
                labels = MeanLabel.getAllLabel(temp, -1);// 获取子意象所有labels
                topLabel.offsets.add(labels[0]);
                labels[0].relateTo = topLabel;
            }
            temp = temp.getNext();
        }
        attr_addPlatform(topLabel);
    }

    private void attr_addPlatform(MeanLabel father) {
        MeanPlatform platform = new MeanPlatform(father);
        meanPlatforms.add(platform);
        rightPanel.add(platform);
        reSetAttrHeight();
    }

    public void attr_clear() {
        rightPanel.removeAll();
    }

    private void meanOpsAddAndGo(String... strings) {
        callBackAll();// 召回
        handler.recoveryTextColor();// 撤销选择操作
        s_add(meanOpsMenu, sliderOfMeanOps, true, strings);
        handler.posAdding = false;// 打开右边滑动菜单时结束此标记
        info_refreshInfo(pre);
        sliderOfMeanOps.goOn();
    }

    // INPUTER*********
    public void deleteMean(MeanLabel label) {
        if (label.relateTo == null) {
            rightPanel.remove(label.group_plat);
            meanPlatforms.remove(label.group_plat);
        } else {
            label.relateTo.group_plat.removePlat(label.group_plat);
            label.relateTo.group_plat.reSetVisible();
        }
        reSetAttrHeight();
        info_refreshInfo(ALL);
    }

    public void deleteAttr(MeanLabel label) {
        label.relateTo.offsets.remove(label); // 从标签链表中删除
        label.relateTo.group_plat.removeAttr(label);// 从Platform中删除
    }

    public void deleteLoc(SelectLabel sl) {
        locSelecter.remove(sl);
        locSelecter.repaint();
    }

    /**
     * 刷新信息版（附带刷新属性版）
     */
    public void info_refreshInfo(int order) {
        if (info_charNums == null) {
            info.add(info_charNums = createInfoLabel());
            info.add(info_mainNums = createInfoLabel());
            info.add(info_allNums = createInfoLabel());
        }
        info.setVisible(false);
        if ((order == charN || order == ALL) && handler.getContext() != null)
            info_charNums.setText(" 总字数：" + handler.getContext().length());
        if (order == main || order == ALL)
            info_mainNums.setText(" 主意象：" + handler.mainMean.size());
        if (order == all || order == ALL)
            info_allNums.setText(" 总意象：" + handler.allMean.size());
        info.setVisible(true);
        rightPanel.setVisible(false);
        rightPanel.setVisible(true);
    }

    private JLabel createInfoLabel() {
        JLabel label = new JLabel();
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setBackground(Color.BLACK);
        label.setForeground(Color.white);
        label.setText("");
        label.setPreferredSize(new Dimension(130, 30));
        label.setFont(new Font(Constant.boldfaceName, Font.BOLD, 14));
        return label;
    }
    public void showMenus_New(boolean selfSelect) {
        String combine = handler.allMean.isEmpty() ? "" : "Combine";
        if (selfSelect)
            textOpsAddAndGo("Add_mean", combine, "Revoke_last", "Revoke");
    }

    public void showMenus_MeanOperate() {
        Mean selected = preSelected.sourceMean;
        if (selected.getInner_id() != 0 || selected.haveNext())
            meanOpsAddAndGo("Apart", "Combine", "Delete", "Revoke");
        else
            meanOpsAddAndGo("Combine", "Delete", "Revoke");
    }

    public void showMenus_AttrOperate() {
        meanOpsAddAndGo("Delete", "Modify", "Revoke");
    }

    public void showMenus_LocOperate() {
//		meanOpsAddAndGo("Delete", "Revoke"); // Disappear Loc operations
    }

    public void showMenus_Revoke() {
        textOpsAddAndGo("Revoke");
    }

    public void showMenus_Confirm_Revoke() {
        textOpsAddAndGo("Confirm", "Revoke");
    }

    /**
     * 升级测试。。 显示属性显示板
     */
    public void showShower(Mean mean) {
        callBackAll();
        preMean = mean;
        String attrs[] = mean.getAttributes();
        m.occupier.setVisible(true);
        m.confirmer.setVisible(false);
        m.normalAttr.removeAll();
        m.normalAttr.repaint();
        for (int i = 0; i < m.attrsName.length; i++) {
            m.attrOptions[i].refresh();
            if (attrs[i] != null)
                m.attrOptions[i].setRecord(attrs[i]);
        }
        if (!sliderOfAttrSetter.isGoing())
            sliderOfAttrSetter.goOn();
    }

    public void showConfirmer(boolean show) {
        m.confirmer.setVisible(show);
        m.occupier.setVisible(!show);
    }

    /**
     * @param isMean 是否是要归并意象
     */
    public void showSelector(boolean isMean) {
        locSelecter.removeAll();
        SelectLabel allLabel[] = {};
        if (isMean)
            allLabel = SelectLabel.allMeanLabel();
        for (SelectLabel anAllLabel : allLabel) {
            locSelecter.add(anAllLabel);
        }
        locSelecter.setVisible(false);
        locSelecter.setVisible(true);
        sliderOfLocSelector.goOn();
    }

    public void unableAttr() {
        rightPanel.setEnabled(false);
    }

    public void ableAttr() {
        rightPanel.setEnabled(true);
    }

    public void clear() {
        rightPanel.removeAll();
        reSetOrder();
    }

    // 设置高度
    public void reSetAttrHeight() {
        int sum = 0;
        for (MeanPlatform aQueue : meanPlatforms) {
            sum += aQueue.getHeight();
        }
        rightPanel.setPreferredSize(new Dimension(m.defaultAttrWidth, sum));
    }

    // 确认框
    public void hide() {
        m.hider.setVisible(true);
        m.repaint();
        m.setEnabled(false);
    }

    public void show() {
        m.hider.setVisible(false);
        m.setEnabled(true);
    }
}
